package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

var (
	content     = make(chan string, 1000)
	readFileCh  = make(chan struct{}, 3)
	writeFileCh = make(chan struct{}, 0)
)

func ReadFile(file string) {
	fine, err := os.Open(file)
	if err != nil {
		fmt.Println("err:", err)
	}
	defer fine.Close()
	reader := bufio.NewReader(fine)
	for {
		line, err := reader.ReadString('\n')
		if err == nil {
			content <- line
		} else {
			if err == io.EOF {
				if len(line) > 0 { // 输入文件的最后一行没有换行符
					content <- (line + "\n")
				}
				break
			} else {
				fmt.Println("err:", err)
			}
		}
	}

	// 每次读取文件后都去content的管道中获取一个元素
	<-readFileCh
	if len(readFileCh) == 0 {
		close(content)
	}
}

func WriteFile(fileWrite string) {
	fine, err := os.OpenFile(fileWrite, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
	if err != nil {
		fmt.Println("err:", err)
	}
	defer fine.Close()
	writer := bufio.NewWriter(fine)
	for line := range content {
		writer.WriteString(line)
	}
	writer.Flush()

	// 写完直接给writeFileCh赋值null struct
	writeFileCh <- struct{}{}
}

func FileMergeTxtMain() {
	for i := 0; i < 3; i++ {
		readFileCh <- struct{}{}
	}
	go ReadFile("data/1.txt")
	go ReadFile("data/2.txt")
	go ReadFile("data/3.txt")

	go WriteFile("data/big.txt")
	// 当代码运行时，直接运行到这里发现writeFileCh管道为空，则会一直阻塞，直至所有协程运行完毕
	// 运行过程中，当最后一个WriteFile方法运行完成后(在writeFileCh管道中塞了一个数据)，则从writeFileCh管道中读到了数据，程序结束
	<-writeFileCh
}
